﻿using Coldairarrow.Util;
using JNPF.Logging;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using PARK.CardAcct.Entitys;
using PARK.CardAcct.Entitys.Dto.Cardtypes;
using PARK.Common.Core.Manager;
using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Consumer.Entity;
using PARK.Consumer.Entitys;
using PARK.Consumer.Entitys.Dto.ConsumBill;
using PARK.Consumer.Entitys.Dto.ConsumMachine;
using PARK.Consumer.Entitys.Dto.ConsumMerchant;
using PARK.Consumer.Entitys.Dto.ConsumStatis;
using PARK.Consumer.Entitys.Dto.Wechat;
using PARK.Consumer.Interfaces.ConsumBill;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using PARK.JsonSerialization;
using PARK.System.Interfaces.System;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace PARK.Consumer
{
    /// <summary>
    /// 消费记录服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Wechat", Name = "Consum", Order = 200)]
    [Route("api/wechat/[controller]")]
    public class WechatConsBillService : IWechatConsBillService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<ConsumBillEntity> _consumBillRepository;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;
        private readonly ISysConfigService _sysConfigService;
        /// <summary>
        /// 初始化一个<see cref="WechatConsBillService"/>类型的新实例
        /// </summary>
        public WechatConsBillService(
            ISqlSugarRepository<ConsumBillEntity> consumBillRepository,
            IUserManager userManager,
            ISysConfigService sysConfigService)
        {
            _consumBillRepository = consumBillRepository;
            _db = _consumBillRepository.Context;
            _userManager = userManager;
            _sysConfigService = sysConfigService;
        }

        #region 获取消费记录
        /// <summary>
        /// 获取消费记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetRecordList")]
        public async Task<dynamic> GetRecordList([FromQuery] ConsumBillListQueryInput input)
        {
            var sidx = input.sidx == null ? "txnDate" : input.sidx;
            var userInfo = await _userManager.GetUserInfo();
            var _EmployeeId = "0";
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                _EmployeeId = userInfo.EmployeeId;
            }
            //消费日期
            List<string> queryTxnDate = input.txnDate != null ? input.txnDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBillDate = queryTxnDate != null ? Ext.GetDateTime(queryTxnDate.First()) : null;
            DateTime? endBillDate = queryTxnDate != null ? Ext.GetDateTime(queryTxnDate.Last()) : null;

            var data = await _db.Queryable<ConsumBillEntity>()
                .Where(a => a.EmployeeId.Equals(_EmployeeId))
                .Where(a => a.TxnResult == 1)
                //消费日期
                .WhereIF(queryTxnDate != null, p => p.TxnDate >= new DateTime(startBillDate.ToDate().Year, startBillDate.ToDate().Month, startBillDate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryTxnDate != null, p => p.TxnDate <= new DateTime(endBillDate.ToDate().Year, endBillDate.ToDate().Month, endBillDate.ToDate().Day, 23, 59, 59))
                .Select(it => new ConsumBillListOutput
                {
                    id = it.Id,
                    merchantName = it.MerchantName,
                    cardNo = it.CardNo,
                    reallName = it.ReallName,
                    departName = it.DepartName,
                    txnTotalAmt = it.TxnTotalAmt,
                    txnSeq = it.TxnSeq,
                    txnDate = Convert.ToDateTime(it.TxnDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    txnResult = it.TxnResult,
                    requestId = it.RequestId,
                    payWay = it.PayWay,
                    uploadTime = it.UploadTime,
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<ConsumBillListOutput>.SqlSugarPageResult(data);
        }
        #endregion

        #region 获取消费详情
        /// <summary>
        /// 获取消费详情
        /// </summary>
        /// <param name="id">参数</param>
        /// <returns></returns>
        [HttpGet("GetBillInfo")]
        public async Task<dynamic> GetBillInfo(string id)
        {
            var entity = await _db.Queryable<ConsumBillEntity>().FirstAsync(p => p.Id == id);
            var output = entity.Adapt<ConsumBillInfoOutput>();
            return output;
        }
        #endregion

        #region 获取消费二维码(旧方法)
        /// <summary>
        /// 获取消费二维码
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetQrcodeOld")]
        public async Task<QrcodeDto> GetQrcodeOld()
        {
            QrcodeDto output = new QrcodeDto()
            {
                ret = 0,
                msg = "生成异常",
                QRcode = "",
                ExpiryEndDate = DateTime.Now.AddDays(-1),
                WelfareBalance = 0,
                RechargeBalance = 0
            };
            //当前用户
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                var entity = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                if (entity != null && entity.AccStatus == 1)
                {
                    var sysConfig = await _sysConfigService.GetInfo("QHConfig", "qinhua_app_qrcode");
                    var dto = new QrcodeInputDto();
                    //获取余额
                    dto.EmployeeId = entity.EmployeeId;
                    dto.CardNo = entity.CardNo;
                    dto.JobNo = entity.JobNum;
                    dto.ReallName = entity.RealName;
                    dto.DepartId = entity.DepartId;
                    dto.DepartName = entity.DepartName;
                    dto.dbDate = DateTime.Now;
                    var expir = int.Parse(sysConfig.Value);
                    dto.ExpiryEndDate = DateTime.Now.AddSeconds(expir);
                    //生成的码对象
                    var QrcodeEntity = dto.Adapt<ConsumQrcodeEntity>();
                    QrcodeEntity.Id = YitIdHelper.NextId().ToString();
                    QrcodeEntity.QRcode = PARK.Utils.AES.AESEncrypt(QrcodeEntity.Id);
                    QrcodeEntity.CompanyId = userInfo.companyId;
                    QrcodeEntity.CompanyName = userInfo.companyName;
                    //码入库
                    var isOk = await _db.Insertable(QrcodeEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                    if ((isOk > 0))
                    {
                        output.ret = 1;
                        output.msg = "ok";
                        output.QRcode = QrcodeEntity.QRcode;
                        output.ExpiryEndDate = dto.ExpiryEndDate;
                        output.WelfareBalance = entity.WelfareBalance;
                        output.RechargeBalance = entity.RechargeBalance;
                    }
                }
                else
                {
                    output.ret = 0;
                    output.msg = "账户非正常,无法生码";
                }
            }
            else
            {
                output.ret = 0;
                output.msg = "非法用户,无法生码";
            }
            return output;
        }
        #endregion

        #region 获取消费二维码
        /// <summary>
        /// 获取消费二维码
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetQrcode")]
        public async Task<QrcodeDto> GetQrcode()
        {
            QrcodeDto output = new QrcodeDto()
            {
                ret = 0,
                msg = "生成异常",
                QRcode = "",
                ExpiryEndDate = DateTime.Now.AddDays(-1),
                WelfareBalance = 0,
                RechargeBalance = 0
            };
            //当前用户
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                var entity = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                if (entity != null && entity.AccStatus == 1)
                {
                    var sysConfig = await _sysConfigService.GetInfo("QHConfig", "qinhua_app_qrcode");
                    var dto = new QrcodeInputDto();
                    //获取余额
                    dto.EmployeeId = entity.EmployeeId;
                    dto.CardNo = entity.CardNo;
                    dto.JobNo = entity.JobNum;
                    dto.ReallName = entity.RealName;
                    dto.DepartId = entity.DepartId;
                    dto.DepartName = entity.DepartName;
                    dto.dbDate = DateTime.Now;
                    var expir = int.Parse(sysConfig.Value);
                    dto.ExpiryEndDate = DateTime.Now.AddSeconds(expir);
                    //生成的码对象
                    var _QRcode = QRcodeUtil.CreateQRcode(entity.CardTypeCode, entity.CardNo, dto.ExpiryEndDate);
                    var QrcodeEntity = dto.Adapt<ConsumQrcodeEntity>();
                    QrcodeEntity.Id = YitIdHelper.NextId().ToString();
                    QrcodeEntity.QRcode = PARK.Utils.AES.AESEncrypt(_QRcode);
                    QrcodeEntity.CompanyId = userInfo.companyId;
                    QrcodeEntity.CompanyName = userInfo.companyName;
                    //码入库
                    new LoggEx().Info("原码:" + _QRcode + ";加密后:" + QrcodeEntity.QRcode);
                    var isOk = await _db.Insertable(QrcodeEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                    if ((isOk > 0))
                    {
                        output.ret = 1;
                        output.msg = "ok";
                        output.QRcode = QrcodeEntity.QRcode;
                        output.ExpiryEndDate = dto.ExpiryEndDate;
                        output.WelfareBalance = entity.WelfareBalance;
                        output.RechargeBalance = entity.RechargeBalance;
                    }
                }
                else
                {
                    output.ret = 0;
                    output.msg = "账户非正常,无法生码";
                }
            }
            else
            {
                output.ret = 0;
                output.msg = "非法用户,无法生码";
            }
            return output;
        }
        #endregion


        #region 餐次统计
        /// <summary>
        /// 获取商户档案列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetMerchantSelector")]
        public async Task<dynamic> GetMerchantSelector()
        {
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                if (_Employee != null)
                {
                    var data = await _db.Queryable<ConsumMerchantEntity>()
                        .Where(p => p.CompanyId.Equals(_Employee.CompanyId))//权限
                        .Where(d => d.IsDeleted != 1)
                        .Select(it => new ConsumMerchantListOutput
                        {
                            merchantId = it.MerchantId,
                            merchantCode = it.MerchantCode,
                            merchantName = it.MerchantName,
                            chargepername = it.Chargepername,
                            chargepertel = it.Chargepertel,
                            remarks = it.Remarks,
                        }).MergeTable().ToListAsync();
                    return data;
                }
                else
                    return null;
            }
            else
                return null;
        }
        /// <summary>
        /// 获取某商户下消费机下拉
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetMerMachSelector")]
        public async Task<dynamic> GetMerMachSelector(string MerchantId)
        {
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                if (_Employee != null)
                {
                    var data = await _db.Queryable<ConsumMachineEntity>().Where(t => t.IsDeleted == 0)
                        //公司权限
                        .Where(p => p.CompanyId.Equals(_Employee.CompanyId))
                        //公司权限
                        .WhereIF(!string.IsNullOrEmpty(MerchantId), p => p.MerchantId.Equals(MerchantId))
                        .ToListAsync();
                    var treeList = new List<ConsumMachineCrInput>();
                    data.ForEach(item =>
                    {
                        treeList.Add(new ConsumMachineCrInput()
                        {
                            machineId = item.MachineId,
                            machineName = item.MachineName,
                        });
                    });
                    return treeList;
                }
                else
                    return null;
            }
            else
                return null;
        }
        /// <summary>
        /// 获取卡片类型下拉
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetCardTypeSelector")]
        public async Task<dynamic> GetCardTypeSelector()
        {

            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                if (_Employee != null)
                {
                    var data = await _db.Queryable<CardtypesEntity>().Where(t => t.IsDeleted == 0 && t.EnabledMark == 1 && t.CompanyId == _Employee.CompanyId)
                            .Select(it => new CardtypesSelectorOutput
                            {
                                CardTypeId = it.Id,
                                CardTypeName = it.CardTypeName
                            }).ToListAsync();
                    return data;
                }
                else
                    return null;
            }
            else
                return null;
        }
        /// <summary>
        /// 餐次统计
        /// </summary>
        /// <param name="txnBegDate"></param>
        /// <param name="txnEndDate"></param>
        /// <param name="merchantId"></param>
        /// <param name="machineId"></param>
        /// <param name="cardTypeId"></param>
        /// <returns></returns>
        [HttpGet("GetTimeIntervalRep")]
        public async Task<dynamic> GetTimeIntervalRep(string txnBegDate, string txnEndDate, string merchantId, string machineId, string cardTypeId)
        {
            try
            {
                //new LoggEx().Info("1>收到参数:txnBegDate->"+ txnBegDate+ ",txnEndDate->"+ txnEndDate+ ",merchantId->"+ merchantId+ ",machineId->"+ machineId+ ",cardTypeId->"+ cardTypeId);
                var userInfo = await _userManager.GetUserInfo();
                if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
                {
                    var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                    if (_Employee != null)
                    {
                        var startDate = DateTime.Now;
                        var endDate = DateTime.Now;
                        if (!string.IsNullOrEmpty(txnBegDate))
                            startDate = Convert.ToDateTime(txnBegDate);
                        if (!string.IsNullOrEmpty(txnEndDate))
                            endDate = Convert.ToDateTime(txnEndDate);

                        //new LoggEx().Info("2>传入参数:companyId->"+ _Employee.CompanyId + ",startDate->" + startDate + ",endDate->" + endDate + ",merchantId->" + merchantId + ",machineId->" + machineId + ",cardTypeId->" + cardTypeId);

                        var Pars = new List<SugarParameter>(){
                              new SugarParameter("@companyId",_Employee.CompanyId),
                              new SugarParameter("@begDate",startDate),
                              new SugarParameter("@endDate",endDate),
                              new SugarParameter("@merchantId",!string.IsNullOrEmpty(merchantId)?merchantId:""),
                              new SugarParameter("@machineId",!string.IsNullOrEmpty(machineId)?machineId:""),
                              new SugarParameter("@cardTypeId",!string.IsNullOrEmpty(cardTypeId)?cardTypeId:"")
                            };
                        var Repdt = _db.Ado.UseStoredProcedure().GetDataTable("P_Rep_GetTimeIntervalWechat", Pars);
                        var output = TableEntity.TableToEntity<TimeIntervalListWechatOutPut>(Repdt);
                        return output;
                    }
                    else
                        return null;
                }
                else
                {
                    return null;
                }
            }
            catch(Exception ex)
            {
                return null;
            }
        }
        #endregion
    }
}
